import { ATeamCombat } from "GameLoop/WorldState/EntityManager/Entitys";
import { PositionHelper } from "utils/position/PositionHelper";
import { IDefendStrategy } from "./Base";
import { StationNetwork } from "GameLoop/Path/StationNetwork";
import { ETaskState } from "GameLoop/DecisionMaking/TaskDeclare/type";

/**
 * 中央9房的sourceKeeper 防守
 */
export class DefendStrategy3 extends IDefendStrategy
{
    public assignTarget(room:Room,task:ITask<ITeamTaskData<"defend">>,teams:ATeamCombat[],creeps:Creep[]): ETaskState 
    {
        const workroom = Game.rooms[task.data.room];
        // 设置移动目标,测试
        let goal = this.getMoveGoal(task.data.room,workroom);
        if((task.data.arg as any).canIngoreMin === undefined)
        {
            (task.data.arg as any).canIngoreMin=true;
            const outMine = room.getEntitys("OutMineEntity");
            const minerial = workroom.getMinerial()[0];
            for(const e of outMine)
            {
                if(e.roomName == workroom.name)
                {
                    if(e.getPath().find(p=>p.distance(minerial.pos)<=4))
                    {
                        (task.data.arg as any).canIngoreMin = false;
                        break;
                    }
                }
            }
        }
        if(workroom)
        {
            
            const enemy:Creep[] = [];
            for(const creepid of task.data.arg.enemy)
            {
                const e = Game.getObjectById(creepid );
                if(e)
                {
                    enemy.push(e);
                }
            }
            if(!task.data.arg.structures || task.data.arg.structures.length ==0)
            {
                const sstructures = workroom.find(FIND_STRUCTURES).filter( e=> e.structureType == STRUCTURE_KEEPER_LAIR) as StructureKeeperLair[];
                task.data.arg.structures  = sstructures.map(e=>e.id);
            }
            // 同时对房间环境进行分析
            // const groups = WarStrategy.classifyEnemy(enemy);
            // if((task.data.arg as any).canIngoreMin)
            // {
            //     const events = workroom.getWorld().PollEvents(workroom.name);
            //     if(events  )
            //     {
            //         const attacker = events.getAttacker<Creep>();
            //         if(attacker)
            //         {
            //             enemy.push(...attacker);
            //             (task.data.arg as any).canIngoreMin = false;
            //         }
            //     }
            // }
            
            task.data.arg.enemy = _.uniq(enemy.map(e=>e.id));
            task.data.arg.structures = task.data.arg.structures.filter(e=>Game.getObjectById(e));
            if( task.data.arg.enemy.length ==0)
            {
                // 移动到指定建筑附近
                let ingoreMinerial = false;
                const minerial = workroom.getMinerial()[0];
                {
                    // 元素款也有路径判断没有用、
                    if(minerial.mineralAmount==0 && (task.data.arg as any).canIngoreMin)
                    {
                        ingoreMinerial = true;
                    }
                }
                let sstructures = (task.data.arg.structures.map(e=>Game.getObjectById(e))  as StructureKeeperLair[])
                if(ingoreMinerial)
                {
                    sstructures = sstructures.filter(s=>s.pos.distance(minerial.pos)>4);
                }
                if(sstructures.length)
                {
                    const nearestLair =  _.min(sstructures,e=>e.ticksToSpawn?e.ticksToSpawn:0);
                    if(workroom.canExecute(5))
                    {
                        goal = {pos:nearestLair.pos,range:1};
                        this.setCreepTactic(creeps,{goal:goal,type:2,targets:[ ]},task.data.room,this.correctCreep);
                        this.setTeamTractic(teams,{goal:goal,type:2,targets:[ ]},task.data.room,this.correctTeam);
                    }
                    if(!nearestLair.ticksToSpawn || workroom.canExecute(5))
                    {
                        let creeps = workroom.find(FIND_HOSTILE_CREEPS);
                        if(ingoreMinerial)
                        {
                            creeps = creeps.filter(e=>e.pos.distance(minerial.pos)>4);
                        }
                        task.data.arg.enemy = creeps.map(e=>e.id);
                    }
                }
                else 
                {
                    goal = {pos:PositionHelper.Create({x:25,y:25,roomName:workroom.name}) ,range:1};
                    this.setCreepTactic(creeps,{goal:goal,type:2,targets:[ ]},task.data.room,this.correctCreep);
                    this.setTeamTractic(teams,{goal:goal,type:2,targets:[ ]},task.data.room,this.correctTeam);
                    const cache = workroom.getWorld().PollHostiles(workroom.name);
                    if(cache)
                    {
                        task.data.arg.enemy = cache.cacheData.filter(e=>Game.getObjectById(e.id)).map(e=>e.id);
                    }
                    // task.data.arg.enemy = workroom.
                }
            }
            else
            {
                // 干爬
                
                this.setCreepTactic(creeps,{goal:undefined,type:2,targets:[PositionHelper.getObjectRef(_.min(enemy,e=>e.ticksToLive))]},task.data.room,this.correctCreep);
                this.setTeamTractic(teams,{goal:undefined,type:2,targets:[PositionHelper.getObjectRef(_.min(enemy,e=>e.ticksToLive))]},task.data.room,this.correctTeam);
            }
            this.updateTeamAroundHostile(teams,enemy);
            this.updateCreepAroundHostile(creeps,enemy);
            
            
            // this.deployStrategy1(teams,task.data);
        }
        else 
        {
            // 没视野
            goal = {pos:PositionHelper.Create({x:25,y:25,roomName:task.data.room}) ,range:1};
                this.setCreepTactic(creeps,{goal:goal,type:2,targets:[ ]},task.data.room,this.correctCreep);
                this.setTeamTractic(teams,{goal:goal,type:2,targets:[ ]},task.data.room,this.correctTeam);
        }
        return ETaskState.Running
    }
}
